//学习目标
// 能够说出什么是内置对象
// 能够根据文档查询指定api的使用方法
// 能够使用Math对象的常用方法
// 能够使用Date对象的常用方法
// 能够使用String对象的常用方法

// js中的对象分为3种：自定义对象，内置对象，浏览器对象
// 前面两种对象是js基础 属于ECMAScript 第三个浏览器对象是JS独有的

// Math对象，不是一个构造函数，所以我们不需要new来调用，而是直接使用里面的属性和方法即可
Math.E; //可以直接使用

// 封装自己的数学对象 里面有PI最大值和最小值
var myMath = {
    PI: 3.141592653,
    max: function () {
        var max = arguments[0];
        for (var i = 1; i < arguments.length; i++) {
            if (arguments[i] > max) {
                max = arguments[i];
            }
            return max;
        }
    },
    min: function () {
        var min = arguments[0];
        for (var i = 1; i < arguments.length; i++) {
            if (arguments[i] < min) {
                min = arguments[i];
            }
            return min;
        }
    },
};

console.log(myMath.PI);
console.log(myMath.max(1, 5, 9));
//对于math对象掌握如何获取最大值 最小值 平均值  随机数等方法

//Date对象 日期对象需要通过调用Date构造函数来实例化日期对象
var date = new Date();
console.log(date); //未输入任何参数则返回 系统当前时间
// 参数的写法：数字型2019,10,01 或者字符型 '2019-10-1 8:8:8'  因此最好使用字符型作为参数
var date1 = new Date(2019, 10, 1);
console.log(date1); //这里返回的是11月而不是10月

// 日期格式化
// getFullYear()、getDate()、getmonth()、getDay()等函数，注意getMonth函数获取当前月(0-11)、getDay()获取星期几(周日0 到周六6)

var date = new Date();
console.log(date.getFullYear()); //返回当前的年 2019
console.log(date.getMonth() + 1); //当前月份记得+1
console.log(date.getDate()); //返回几号
//返回一个今天是 2022年8月18日 星期四
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
var day = date.getDay();
console.log('今天是' + year + '年' + month + '月' + dates + '日' + arr[day]);

//返回时间格式 时:分:秒 如09:40:10
function getTime() {
    var time = new date();
    var h = time.getHours();
    h = h < 10 ? '0' + h : h;
    var m = time.getMinutes();
    m = m < 10 ? '0' + m : m;
    var s = time.getSeconds();
    s = s < 10 ? '0' + s : s;
    return h + ':' + m + ':' + s;
}

//获得距1970年1月1号过了多少毫秒数
//  1、通过valueOf() getTime()
var date = new Date();
console.log(date.valueOf());
// 2、简单的写法
var date1 = +new Date(); //返回的就是总毫秒数
console.log(date1);
// 3、H5新增的方法 获得总的毫秒数
console.log(Date.now());

// 倒计时小案例
// 思路：输入的时间减去现在的时间既是倒计时 ，但是不能直接减，因为05分减去25分是负数，应当用时间戳来做，
// 用户输入时间总毫秒数减去现在时间总的毫秒数，得到的就是剩余时间的毫秒数
// 把剩余时间的总毫秒数转换为天、时、分、秒
// 转换公式如下
// d=parseInt(总秒数/60/60/24); 计算天数
// h=parseInt(总秒数/60/60%24)  计算小时
// m=parseInt(总秒数/60%60) 计算分钟

function countDown(time) {
    var nowTime = +new Date(); //返回当前时间的毫秒数
    var inputTime = +new Date(time); //返回的是用户输入时间总的毫秒数
    var times = (inputTime - nowTime) / 1000; //time就是剩余时间总的秒数，/1000将毫秒换算成秒数
    var d = parseInt(times / 60 / 60 / 24); //天
    d = d < 10 ? '0' + d : d;
    var h = parseInt((times / 60 / 60) % 24); //小时
    h = h < 10 ? '0' + h : h;
    var m = parseInt((times / 60) % 60); //分钟
    m = m < 10 ? '0' + m : m;
    var s = parseInt(times % 60); //秒
    return d + '天' + h + '小时' + m + '分' + s + '秒';
}

console.log(countDown('2019-5-1 18:00:00'));
var date = new Date();
console.log(date);

//数组对象
//创建数组的两种方式
var arr = [1, 2, 3];
console.log(arr[0]);

// 利用new Array()
var arr1 = new Array(2); //数组长度为2 里面有2个空的数组元素
var arr1 = new Array(2, 3); //这时传递的就是数组 [2,3]

//检测是否是数组
// instanceof 运算符 可以用来检测是否为数组
var arr = [];
var obj = {};
console.log(arr instanceof Array);
console.log(obj instanceof Array);

//Array.isArray() 用于确定传递的值是否是一个Array H5新增的方法 ie9以上版本支持
// 数组相关操作 添加删除数组元素的方法
// 1、push() 在数组末尾 添加一个或者多个数组元素
var arr = [1, 2, 3];
// arr[3]=4;
arr.push(4, 'pink');
// （1）、push是可以给数组追加新元素
// （2）、push() 参数直接写 数组元素就可以了
// （3）、push完毕后 返回的结果是 新数组的长度
// （4）、原数组也会发生变化

// 2、unshift在数组开头 添加一个或者多个数组元素
arr.unshift('red');
console.log(arr);
// 特点 和push是一样的，返回的结果是新数组的长度，原数组也会发生变化 只不过是在开头进行添加

// 删除数组
arr.pop();
// （1）、pop是可以删除数组的最后一个元素  一次只能删除一个元素
// （2）、pop() 参数直接写 数组元素就可以了
// （3）、pop完毕后 返回的结果是 删除的元素
// （4）、原数组也会发生变化
arr.shift(); //特点同 pop 删除的是数组中的第一个元素

//数组排序
// reverse() 颠倒数组中元素的顺序 无参数  该方法会改变原来的数组 返回新数组
// sort() 对数组元素进行排序  该方法会改变原来的数组 返回新数组  sort是冒泡排序
var arr1 = [13, 4, 77, 1, 7];
arr1.sort(); //排序结果是 1 13 7 77 因为默认的是使用字符比较的方式

arr1.sort(function (a, b) {
    return a - b; //升序的顺序排列
    // return b-a;降序排列
}); //传入比较函数

// 获取数组元素的索引 indexof(数组元素) 返回该数组元素的索引号
// 只返回第一个满足条件的索引号,找不到返回-1
var arr = ['red', 'green', 'blue', 'pink', 'blue'];
console.log(arr.indexOf('blue'));

//lastIndexOf从后往前查找
console.log(arr.lastIndexOf('blue'));

// 数组去重
// 思路: 遍历旧数组,然后拿旧数组元素去查询新数组,如果该元素在新数组内则不添加
// 判断是否在新数组里存在使用indexOF,如果返回的是-1则说明 新数组里没有改元素

function unique(arr) {
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        if (newArr.indexOf(arr[i]) === -1) {
            newArr.push(arr[i]);
        }
    }
    return newArr;
}
var demo = unique(['c', 'a', 'z', 'a', 'x', 'a', 'c', 'b']);
console.log(demo);

// 数组转化为字符串
// toString()把数组转化为字符串,逗号分隔每一项 返回一个字符串
// join('分隔符')把数组中的一个元素转化为字符串  返回一个字符串

var arr = [1, 2, 3];
console.log(arr.toString()); //返回 1,2,3

var arr1 = ['green', 'blue', 'pink'];
console.log(arr.join('-')); //返回green-blue-pink
console.log(arr.join('&')); // 在表单中会经常使用到

//其他常用的方法 concat()连接两个数组,不影响原数组，返回一个新数组
// slice(begin,end) 返回被截取项目的新数组
const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);

// slice(begin,end) 返回被截取项目的新数组，不修改原数组

// array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
// start修改的位置，deleteCount要移除数组元素的个数，item要添加进数组的元素

// 字符串对象
var str = 'andy';
console.log(str.length);
// 对象才有属性和方法  复杂数据类型才有属性和方法
// 简单数据类型 为什么会有length属性呢？
// 基本包装类型：就是把简单数据类型 包装成了 复杂数据类型
var temp = new String('andy');
//再把临时变量的值给str
str = temp;
//销毁这个临时变量
temp = null;

// 还有以下三种包装的数据类型：String、Number、Boolean
// 字符串不可变  因为字符串改变实际上是指向的地址变了，内存中新开辟了一块内存空间
// 因此不要再大量拼接字符串
var str = '';
for (var i = 0; i < 1000000; i++) {
    str += i;
}
console.log(str);
//字符串所有的方法  都不会修改字符串本身,操作完成后会返回一个新的字符串

//根据字符返回位置
//返回字符的位置 indexOf lastIndexOf()    indexOf('某个字符',[开始位置])

// 查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数
// ① 核心算法：先查找第一个o出现的位置
// ② 然后 只要indexOf 返回的结果不是 -1 就继续往后查找
// ③ 因为indexOf 只能查找到第一个，所以后面的查找，利用第二个参数，当前索引加1，从而继续查找

var str1 = 'abcoefoxyozzopp';
var index = str1.indexOf('o');
var num=0;
while (index !== -1) {
    console.log(index);
    num++;
    str.indexOf('o',index+1)  //开始查找的位置往后挪一位
    
}
console.log('o出现的次数是'+num);

//根据位置返回字符
// charAt(index)  返回指定位置的字符(index 字符串的索引号) str.charAt(0);
// charCodeAt(index) 返回指定位置处字符的ASCII码(index 索引号) str.charCodeAt();   常用来判断用户按下了哪个键
// str[index]  获取指定位置处字符 H5新增的

// 判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符，并统计其次数。
// ① 核心算法：利用 charAt() 遍历这个字符串
// ② 把每个字符都存储给对象， 如果对象没有该属性，就为1，如果存在了就 +1
// ③ 遍历对象，得到最大值和该字符

var chars='abcoefoxyozzopp'
var o={}
for(var i=0;i<chars.length;i++){
    var chars = chars.charAt(i)
    if(o[chars]){
        o[chars]+-1
    }else{
        o[chars]=1
    }
}
// 遍历对象
var max=0;
var ch='';
for(var k in o){
    if(o[k]>max){
        max=o[k];
        ch=k;
    }
}
console.log(max);
console.log('最多的字符是'+ch);

// 字符串操作方法  
// concat(str1,str2,str3)等效于+
// substr(start,length) 从start位置开始(索引号),length 取的个数 重点记住这个
// slice(start,end) 从start开始，截取到end位置 end取不到（他们两都是索引号）
// substring(starting,end) end取不到 基本和slice相同 但是不接受负值
// replace('被替换的字符串',’替换用的字符串')  遍历数组 找到一个替换一个
// split('分隔符') 字符串转为数组 
// toUpperCase() 转化大写
// toLowerCase()转化为小写


var str='andyandy'  //只替换第一个字符
console.log(str.replace('a','b'));

//替换所有的字符 如 将'abcoefoxyozzopp'中的所有的o 替换为*
var str1='abcoefoxyozzopp';
while(str1.indexOf('o')!==-1){
    str1=str1.replace("o","*"); //string是不可变的
}
